﻿using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace N2.Web
{
	public class Thumbnail: IImageBuilder
	{
		#region Const
		//TODO make configurable
		const string EmptyImageUrl = "~/Addons/Catalog/UI/Img/no-cover-small.png";
		const string ImageHandlerFileName = "Image.ashx";
		const string ImageHandlerUrl = "~/Templates/UI/" + ImageHandlerFileName;
		
		#endregion Const

		#region Fields
		readonly ContentItem Item;
		#endregion Fields

		#region ctor

		public Thumbnail(ContentItem item)
		{
			this.Item = item;
			//this.Item["ImageUrl"] causes a 'select n + 1' problem
			this.ImageUrl = this.Item.GetDetail<string>("ImageUrl", string.Empty);
		}
		
		#endregion ctor

		#region Properties

		public string ImageUrl { get; protected set; }

		public string AlternateText { get; set; }

		public Unit Width { get; set; }

		public Unit Height { get; set; }

		public string Title { get; set; }

		public string CssClass { get; set; }

		#endregion Properties

		#region Methods

		public static IImageBuilder Of(ContentItem item)
		{
			return new Thumbnail(item);
		}

		public override string ToString()
		{
			var _sb = new StringBuilder();
			using (var _writer = new HtmlTextWriter(new StringWriter(_sb))) {
				Control _ctl = ((IImageBuilder)this).ToControl();
				_ctl.RenderControl(_writer);
			}
			return _sb.ToString();
		}
		
		#endregion Methods

		#region IImageBuilder Members

		IImageBuilder IImageBuilder.Width(Unit width)
		{
			this.Width = width;
			return this;
		}

		IImageBuilder IImageBuilder.Height(Unit height)
		{
			this.Height = height;
			return this;
		}

		IImageBuilder IImageBuilder.Alt(string alternateText)
		{
			this.AlternateText = alternateText;
			return this;
		}

		IImageBuilder IImageBuilder.Title(string title)
		{
			this.Title = title;
			return this;
		}

		IImageBuilder IImageBuilder.Class(string @class)
		{
			this.CssClass = @class;
			return this;
		}
		
		Control IImageBuilder.ToControl()
		{
			var _imageUrl = this.ImageUrl;
			
			bool _hasImage = !string.IsNullOrEmpty(_imageUrl);

			if (!_hasImage) {
				_imageUrl = EmptyImageUrl;
			}

			var _refersToImageHandler = string.Equals(
				VirtualPathUtility.GetFileName(Url.PathPart(_imageUrl)),
				ImageHandlerFileName,
				System.StringComparison.OrdinalIgnoreCase);

			var _url =
				!_refersToImageHandler
						&& (_hasImage || !this.Width.IsEmpty || !this.Height.IsEmpty)
					? Url.Parse(ImageHandlerUrl).SetQueryParameter("img", Url.ToAbsolute(_imageUrl))
					: Url.Parse(_imageUrl);
			
			var _img = new Image {
				AlternateText = 
					string.IsNullOrEmpty(this.AlternateText)
						? this.Item.Title
						: this.AlternateText,
				ToolTip =
					string.IsNullOrEmpty(this.Title)
						? this.Item.Title
						: this.Title,
			};
			//TODO perform unit conversion
			if(!this.Width.IsEmpty && this.Width.Type == UnitType.Pixel) {
				_img.Width = this.Width;
				_url = _url.SetQueryParameter("w", (int)this.Width.Value);
			}

			if(!this.Height.IsEmpty && this.Height.Type == UnitType.Pixel) {
				_img.Height = this.Height;
				_url = _url.SetQueryParameter("h", (int)this.Height.Value);
			}

			if (!string.IsNullOrEmpty(this.CssClass)) {
				_img.CssClass = this.CssClass;
			}

			_img.ImageUrl = Url.ToAbsolute(_url.ToString());

			return _img;
		}

		#endregion
	}
}
